package middleware;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Random;

import logging.Logging;

// implements the logic in case of full replication
public class FullReplicationDatabaseLogic extends AbstractDatabaseLogic {

	Random randomGenerator = new Random();

	public FullReplicationDatabaseLogic(ArrayList<Connection> conns, Queue q) {
		super(conns, q);

	}

	/* (non-Javadoc)
	 * @see middleware.AbstractDatabaseLogic#processQuery()
	 */
	@Override
	public void processStatement() {
		int type;
		String results = null;

		// fetch query
		ClientHandler ch = fetchStatement();

		type = getType(ch);

		// send to database
		if (type == 0) {
			Logging.logEvent(1, "PROCESSING UPDATE", ch.getQuery());
			// send update to all databases ...
			for (int i = 0; i < dbHandler.size(); i++) {
				this.forwardUpdate(ch.getQuery(), i);
			}
			//... and fetch results afterwards
			results = this.fetchResult(0);
			for (int i = 1; i < dbHandler.size(); i++) {
				if (!results.equalsIgnoreCase(this.fetchResult(i))) {
					System.err.println("Error in consistency of results after update: Not all databases updated equally");
				}
				//System.out.println(this.fetchResult(i));
			}
			results = "upi " + results;

		} else if (type == 1) {
			Logging.logEvent(2, "PROCESSING QUERY", ch.getQuery());
			// send to random single database
			int randomNumber;
			randomNumber = randomGenerator.nextInt(dbHandler.size());
			this.forwardQuery(ch.getQuery(), randomNumber);
			
			results = this.fetchResult(randomNumber);

		} else if (type == 2) {
			this.forwardPreparedStatementStruct(ch.getQuery());
			results = "Set prepared Statement";
		}
		ch.returnResult(results);
	}

}
